// /////////////////////////////////////////////////////////////////////////////
//
// Name:            EntityManager.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the EntityManager class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __ENTITYMANAGER_H__
#define __ENTITYMANAGER_H__

// Include files
#include "../dependencies.h"
#include "ReferenceCounted.h"
#include "Entity.h"

// Forward declarations
class Entity;


// EntityManager class
//! The Entity Manager is the central interface point to all entity related functions of this
//! program.
class EntityManager : public ReferenceCounted
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    EntityManager();
    //! Deconstructor
    ~EntityManager();

    //! Initialises the EntityManager.
    void init();
    //! Clears the EntityManager.
    void clear();

    // Reference counting
    //! Increases the reference counter.
    //! @note This is a dummy function.
    void grab();
    //! Decreases the reference counter.
    //! @note This is a dummy function.
    void drop();

    // Methods
    //! Adds the given Entity to the EntityManager
    //! @param entity        Pointer to the Entity to add.
    //! @return True if addition was successful, false if addition was a failure.
    bool addEntity(Entity *entity);
    //! Creates (and adds) an Entity with the given name.
    //! @param name          Name of the Entity.
    //! @param parent        Parent of the entity that is going to be created.
    //! @param assets        Pointer to the AssetGroup that will be used as an alternative
    //!                      source for loading assets instead of the global unmanaged pool.
    //! @param grab          Should the EntityManager add the loaded entity to the internal list?
    //! @return Pointer to the Entity on success, NULL on failure.
    Entity* createEntity(const std::string &name, Entity *parent = NULL, AssetGroup* assets = 0, bool grab = true);
    //! Creates an Entity from the given XML file.
    //! @param fileName      Filename of the entity.
    //! @param parent        Parent of the entity that is going to be created. Will override
    //!                      parent mentioned in the XML file.
    //! @param assets        Pointer to the AssetGroup that will be used as an alternative
    //!                      source for loading assets instead of the global unmanaged pool.
    //! @param grab          Should the EntityManager add the loaded entity to the internal list?
    Entity* createEntityFromXML(const std::string &fileName, Entity *parent = NULL,
                                AssetGroup *assets = NULL, bool grab = true);
    //! Creates an Entity from a XML file through a IXMLReader object.
    //! @param file          Pointer to the IXMLReader object that will be used.
    //! @param parent        Parent of the entity that is going to be created. Will override
    //!                      parent mentioned in the XML file.
    //! @param assets        Pointer to the AssetGroup that will be used as an alternative
    //!                      source for loading assets instead of the global unmanaged pool.
    //! @param grab          Should the EntityManager add the loaded entity to the internal list?
    Entity* createEntityFromXML(IXMLReader *file, Entity *parent = NULL, AssetGroup *assets = NULL,
                                bool grab = true);

    //! Gets the Entity with the given ID.
    //! @return Pointer to the Entity if found, else NULL.
    Entity* getEntity(const u32 id);
    //! Gets the Entity with the given name.
    //! @return Pointer to the Entity if found, else NULL.
    Entity* getEntity(const std::string &name);

    //! Removes all entities from the EntityManager.
    void removeEntities();
    //! Removes the given Entity.
    //! @param entity        Pointer to the Entity to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeEntity(Entity *entity);
    //! Removes the given Entity with the given ID.
    //! @param id            ID of the Entity to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeEntity(const u32 id);
    //! Removes the given Entity with the given name.
    //! @param name          Name of the Entity to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeEntity(const std::string &name);

private:

    // Private members
    vector<Entity*> mEntities;
};

#endif
